package com.easy.dev.manager;

import java.util.ArrayList;
import java.util.List;

public class CacheSql<T> {

    /**
     * 缓存sql长度，达到该容量则触发存储到数据库动作
     */
    private int length;

    /**
     * 缓存时间，当时间达到时也触发存储到数据库动作
     */
    private long time;

    /**
     * 开始时间
     */
    private long start;

    /**
     * 偏移指针
     */
    private volatile int offset = -1;

    /**
     * 存储数据容器
     */
    private transient Object[] datas;

    private Handler handler;

    private Thread thread;

    /**
     * 数据已经被调用，应该将其初始化，保证一个新的开始
     */
    public void init() {
        this.datas = new Object[length];
        this.offset = -1;
        this.start = System.currentTimeMillis();
    }

    private Thread create() {
        Thread thread = new Thread(()->{
            try{
                while(true){
                    if (System.currentTimeMillis()-start > time) {
                        if (this.offset != -1) {
                            invoking();
                        } else {
                            start = System.currentTimeMillis();
                        }
                    } else {
                        Thread.sleep(1000);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return thread;
    }

    public void destroy() {
        this.thread.stop();
    }

    public CacheSql(Handler handler) {
        this(100, 10*60*1000, handler);
    }

    public CacheSql(int count, int time, Handler handler) {
        this.length = count;
        this.datas = new Object[length];
        this.start = System.currentTimeMillis();
        this.time = time;
        this.handler = handler;
        this.thread = create();
        this.thread.start();
    }

    public void add(T data) {
        synchronized(this) {
            int index = getOffset();
            this.datas[index] = data;
            if (offset == length-1) {
                invoking();
            }
        }
    }

    /**
     * 调用外部方法
     */
    public void invoking() {
        synchronized (this){
            int leng = offset+1;
            List<T> ds = new ArrayList<T>(leng);
            for (int i = 0; i < leng; i++) {
                ds.add((T)datas[i]);
            }
            handler.handlerData(ds);
            init();
        }
    }

    public int getOffset() {
        return ++offset;
    }

}
